package com.zpy.playground.redisTest.lettuceConfig;

import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;

import java.time.Duration;

@Component
@Configuration
@Profile("test")
public class RedisTemplateStandAloneConfig {
    @Bean(name = "standaloneRedisTemplate")
    public RedisTemplate<String, Object> redisTemplate(@Qualifier("standaloneConnectionFactory") LettuceConnectionFactory connectionFactory) {
        // 配置redisTemplate
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(connectionFactory);
        redisTemplate.setKeySerializer(new StringRedisSerializer());//key序列化
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());//value序列化
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());//key序列化
        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer()); // value序列化方式采用jackson
        return redisTemplate;
    }

    @Bean(name = "standaloneConnectionFactory")
    public LettuceConnectionFactory connectionFactory(RedisStandAloneConfiguration config) {
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
        redisStandaloneConfiguration.setHostName(config.getHost());
        redisStandaloneConfiguration.setPort(config.getPort());
        redisStandaloneConfiguration.setPassword(config.getPassword());
        redisStandaloneConfiguration.setDatabase(config.getDatabase());

        GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
        poolConfig.setMaxIdle(config.getLettuce().getPool().getMaxIdle());
        poolConfig.setMinIdle(config.getLettuce().getPool().getMinIdle());
        poolConfig.setMaxWait(Duration.ofMillis(config.getLettuce().getPool().getMaxWait()));
        poolConfig.setMaxTotal(config.getLettuce().getPool().getMaxActive());

        LettucePoolingClientConfiguration lettucePoolingClientConfiguration =
            LettucePoolingClientConfiguration.builder()
                .commandTimeout(Duration.ofMillis(config.getLettuce().getCommandTimeout()))
                .shutdownTimeout(Duration.ZERO)
                .poolConfig (poolConfig)
                .build();

        LettuceConnectionFactory lettuceConnectionFactory =
            new LettuceConnectionFactory (
                redisStandaloneConfiguration,
                lettucePoolingClientConfiguration
            );

        // Enables multiple LettuceConnections to share a single native connection. If set to false, every operation on LettuceConnection will open and close a socket.
        lettuceConnectionFactory.setShareNativeConnection(false);

        return lettuceConnectionFactory;
    }
}
